package com.efrei.uchat.message;

import com.efrei.uchat.exception.UChatException;
import com.efrei.uchat.utils.Const;

/**
 * Text message with :
 * <ul>
 * <li>TEXT_C: #id#TEXT_C#croom#authorid#author#text#</li>
 * </ul>
 */
public class TextMessage extends Message {
	
	private String croom;
	private String text;
	private int authorId;
	private String author;
	
	/**
	 * 
	 * @param text
	 * @throws UChatException
	 */
	protected TextMessage(String text) throws UChatException {
		super(text);
		updateFromFields();
	}

	/**
	 * text message from user to public channel
	 * @param text
	 * @param sessionId
	 */
	public TextMessage(String text, int sessionId) {
		super(Headers.TEXT, sessionId);
		updateFromFields();
	}

	/**
	 * text message from user to specific channel
	 * @param text
	 * @param croom
	 * @param authorId
	 * @param author
	 * @param sessionId
	 */
	public TextMessage(String text, String croom, int authorId, String author, int sessionId) {
		super(Headers.TEXT_CHANNEL, sessionId);
		this.croom = croom;
		this.authorId = authorId;
		this.author = author;
		this.text = text;
		
		updateFields();
	}
	
	private void updateFromFields() {
		// update croom
		switch (getType()) {
		case TEXT_CHANNEL:
			{
				// text for a croom
				croom = fields.get(0);
				authorId = Integer.valueOf(fields.get(1));
				author = fields.get(2);
				// get text
				text = getText();
			}
			break;
		default:
			{
				// public text
				croom = Const.PUBLIC_CROOM;
				this.authorId = 0;
				this.author = "unknown";
				// get text
				StringBuilder bb = new StringBuilder();
				int size = fields.size();
				for (int i = 0; i < size; i++) {
					bb.append(fields.get(i)).append("\n");
				}
				this.text = bb.toString();
			}
			break;
		}
	}
	
	private void updateFields() {
		switch (getType()) {
		case TEXT_CHANNEL:
			fields.clear();
			fields.add(croom);
			fields.add(String.valueOf(authorId));
			fields.add(author);
			for (String textPart : buildValidText(text).split("#")) {
				fields.add(textPart);
			}
			break;
		default:
			fields.clear();
			for (String textPart : buildValidText(text).split("#")) {
				fields.add(textPart);
			}
			break;
		}
	}
	
	private String buildValidText(String text) {
		return text.replace("#", "<sep/>").replace("\n", "#");
	}
	
	private String parseValidTextPart(String text) {
		return text.replace("<sep/>", "#");
	}
	
	public String getText() {
		StringBuilder txt = new StringBuilder();
		int nbLines = getNbFields();
		int begin = 2 + (getType()==Headers.TEXT_CHANNEL?3:0);
		
		if(nbLines>begin)
			txt.append(parseValidTextPart(getField(begin)));
		for (int i = begin+1; i < nbLines; i++) {
			txt.append("\n"+parseValidTextPart(getField(i)));
		}
		return txt.toString();
	}
	
	public String getCroom() {
		return croom;
	}
	
	public int getAuthorId() {
		return authorId;
	}
	
	public String getAuthor() {
		return author;
	}
}
